package com.devbobcorn.nekoration.client;

import com.devbobcorn.nekoration.NekoColors;
import com.devbobcorn.nekoration.Nekoration;
import com.devbobcorn.nekoration.blocks.DyeableBlock;
import com.devbobcorn.nekoration.blocks.DyeableDoorBlock;
import com.devbobcorn.nekoration.blocks.DyeableHorizontalBlock;
import com.devbobcorn.nekoration.blocks.DyeableVerticalConnectBlock;
import com.devbobcorn.nekoration.blocks.HalfTimberBlock;
import com.devbobcorn.nekoration.blocks.HalfTimberPillarBlock;
import com.devbobcorn.nekoration.blocks.ModBlocks;
import com.devbobcorn.nekoration.items.DyeableBlockItem;
import com.devbobcorn.nekoration.items.HalfTimberBlockItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.minecraft.client.color.world.BiomeColors;
import net.minecraft.client.color.world.FoliageColors;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.util.Identifier;

public class NekorationClient implements ClientModInitializer {
    public static final Logger LOGGER = LoggerFactory.getLogger(Nekoration.MODID + " client");

    public void onInitializeClient() {
        registerBlockRenderTypes();

        registerBlockColors();
        registerItemColors();

        registerPropertyOverrides();
    }

    public void registerBlockColors() {
        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableBlock))
                return NekoColors.getStoneColorOrLightGray(7);
            return NekoColors.getStoneColorOrLightGray(state.get(DyeableBlock.COLOR));
        }, ModBlocks.STONE_BASE_BOTTOM, ModBlocks.STONE_FRAME_BOTTOM, ModBlocks.STONE_PILLAR_BOTTOM, ModBlocks.STONE_LAYERED,
                ModBlocks.STONE_POT, ModBlocks.STONE_PLANTER);

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableBlock))
                return NekoColors.getNekoColorOrWhite(14);
            return NekoColors.getNekoColorOrWhite(state.get(DyeableBlock.COLOR));
        }, ModBlocks.CANDLE_HOLDER_IRON, ModBlocks.CANDLE_HOLDER_GOLD, ModBlocks.CANDLE_HOLDER_QUARTZ);

        /* ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableBlock))
                return NekoColors.getWoodenColorOrBrown(2);
            return NekoColors.getWoodenColorOrBrown(state.get(DyeableBlock.COLOR));
        }, ModBlocks.EASEL_MENU, ModBlocks.EASEL_MENU_WHITE,
                ModBlocks.CUPBOARD, ModBlocks.SHELF, ModBlocks.WALL_SHELF,
                ModBlocks.GLASS_TABLE, ModBlocks.GLASS_ROUND_TABLE, ModBlocks.ARM_CHAIR,
                ModBlocks.BENCH,
                ModBlocks.DRAWER, ModBlocks.CABINET, ModBlocks.DRAWER_CHEST); */

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableVerticalConnectBlock))
                return NekoColors.getStoneColorOrLightGray(7);
            return NekoColors.getStoneColorOrLightGray(state.get(DyeableVerticalConnectBlock.COLOR));
        }, ModBlocks.STONE_BASE, ModBlocks.STONE_FRAME, ModBlocks.STONE_PILLAR,
                ModBlocks.STONE_DORIC, ModBlocks.STONE_IONIC, ModBlocks.STONE_CORINTHIAN);

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableHorizontalBlock))
                return NekoColors.getStoneColorOrLightGray(7);
            return NekoColors.getStoneColorOrLightGray(state.get(DyeableHorizontalBlock.COLOR));
        }, ModBlocks.WINDOW_SILL, ModBlocks.WINDOW_TOP, ModBlocks.WINDOW_FRAME);

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof HalfTimberBlock))
                return NekoColors.getWoodenColorOrBrown(2);
            return (tintIndex == 0) ? NekoColors.getWoodenColorOrBrown(state.get(HalfTimberBlock.COLOR0)) : NekoColors.getNekoColorOrWhite(state.get(HalfTimberBlock.COLOR1));
        }, ModBlocks.HALF_TIMBER_P0, ModBlocks.HALF_TIMBER_P1, ModBlocks.HALF_TIMBER_P2,
                ModBlocks.HALF_TIMBER_P3, ModBlocks.HALF_TIMBER_P4, ModBlocks.HALF_TIMBER_P5,
                ModBlocks.HALF_TIMBER_P6, ModBlocks.HALF_TIMBER_P7, ModBlocks.HALF_TIMBER_P8,
                ModBlocks.HALF_TIMBER_P9);

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof HalfTimberPillarBlock))
                return (tintIndex == 0) ? NekoColors.getWoodenColorOrBrown(2) : NekoColors.getNekoColorOrWhite(14);
            return (tintIndex == 0) ? NekoColors.getWoodenColorOrBrown(state.get(HalfTimberBlock.COLOR0)) : NekoColors.getNekoColorOrWhite(state.get(HalfTimberBlock.COLOR1));
        }, ModBlocks.HALF_TIMBER_PILLAR_P0, ModBlocks.HALF_TIMBER_PILLAR_P1,
                ModBlocks.HALF_TIMBER_PILLAR_P2);

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableBlock))
                return (tintIndex == 0) ? NekoColors.EnumNekoColor.PURPLE.getColor() : NekoColors.getNekoColorOrWhite(14);
            return (tintIndex == 0) ? BiomeColors.getFoliageColor(view, pos) : NekoColors.getNekoColorOrWhite(state.get(DyeableBlock.COLOR));
        }, ModBlocks.WINDOW_PLANT);

        /* ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof WindowBlock))
                return NekoColors.getWoodenColorOrBrown(2);
            return NekoColors.getWoodenColorOrBrown(state.get(WindowBlock.COLOR));
        }, ModBlocks.WINDOW_SIMPLE, ModBlocks.WINDOW_ARCH, ModBlocks.WINDOW_CROSS, ModBlocks.WINDOW_SHADE,
                ModBlocks.WINDOW_LANCET); */

        ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> {
            if (view == null || pos == null || !(state.getBlock() instanceof DyeableDoorBlock))
                return NekoColors.getNekoColorOrWhite(14);
            return NekoColors.getNekoColorOrWhite(state.get(DyeableDoorBlock.COLOR));
        }, ModBlocks.DOOR_1, ModBlocks.DOOR_2, ModBlocks.DOOR_3, ModBlocks.DOOR_TALL_1,
                ModBlocks.DOOR_TALL_2, ModBlocks.DOOR_TALL_3);

        LOGGER.info("Block Colors Registered.");
    }

    public void registerItemColors() {
        // Default Light Gray:
        ColorProviderRegistry.ITEM.register((stack, tintIndex) -> {
            return NekoColors.getStoneFromNeko(DyeableBlockItem.getColor(stack)).getColor();
        },
        ModBlocks.STONE_BASE_BOTTOM.asItem(), ModBlocks.STONE_FRAME_BOTTOM.asItem(),
        ModBlocks.STONE_PILLAR_BOTTOM.asItem(), ModBlocks.STONE_BASE.asItem(),
        ModBlocks.STONE_FRAME.asItem(), ModBlocks.STONE_PILLAR.asItem(),
        ModBlocks.STONE_DORIC.asItem(), ModBlocks.STONE_IONIC.asItem(),
        ModBlocks.STONE_CORINTHIAN.asItem(), ModBlocks.WINDOW_SILL.asItem(),
        ModBlocks.WINDOW_TOP.asItem(), ModBlocks.WINDOW_FRAME.asItem(),
        ModBlocks.STONE_LAYERED.asItem(), ModBlocks.STONE_POT.asItem(),
        ModBlocks.STONE_PLANTER.asItem());

        // Default White:
        ColorProviderRegistry.ITEM.register((stack, tintIndex) -> {
            return NekoColors.getStoneFromNeko(DyeableBlockItem.getColor(stack)).getColor();
        },
        ModBlocks.CANDLE_HOLDER_IRON.asItem(), ModBlocks.CANDLE_HOLDER_GOLD.asItem(),
        ModBlocks.CANDLE_HOLDER_QUARTZ.asItem());


        // Default White, Flowering Plants:
        ColorProviderRegistry.ITEM.register((stack, tintIndex) -> {
            switch (tintIndex) {
                case 0:
                default:
                    return FoliageColors.getDefaultColor();
                case 1:
                    return DyeableBlockItem.getColor(stack).getColor();
            }
        },
        ModBlocks.WINDOW_PLANT.asItem());

        /* Default Wooden Brown:
        ColorProviderRegistry.ITEM.register((stack, tintIndex) -> {
            return DyeableWoodenBlockItem.getColor(stack).getColor();
        }, 
        ModBlocks.WINDOW_SIMPLE.asItem(), ModBlocks.WINDOW_ARCH.asItem(), ModBlocks.WINDOW_CROSS.asItem(),
        ModBlocks.WINDOW_SHADE.asItem(), ModBlocks.WINDOW_LANCET.asItem(),
        ModBlocks.EASEL_MENU.asItem(), ModBlocks.EASEL_MENU_WHITE.asItem(),
        ModBlocks.GLASS_TABLE.asItem(), ModBlocks.GLASS_ROUND_TABLE.asItem(),
        ModBlocks.CUPBOARD.asItem(), ModBlocks.SHELF.asItem(),
        ModBlocks.WALL_SHELF.asItem(), ModBlocks.BENCH,
        ModBlocks.ARM_CHAIR.asItem(), ModBlocks.DRAWER.asItem(),
        ModBlocks.CABINET.asItem(), ModBlocks.DRAWER_CHEST.asItem()); */

        // Default Wooden Brown, BiDyeable:
        ColorProviderRegistry.ITEM.register((stack, tintIndex) -> {
            switch (tintIndex) {
                case 0:
                default:
                    return HalfTimberBlockItem.getColor0(stack).getColor();
                case 1:
                    return HalfTimberBlockItem.getColor1(stack).getColor();
            }
        },
        ModBlocks.HALF_TIMBER_P0.asItem(), ModBlocks.HALF_TIMBER_P1.asItem(),
        ModBlocks.HALF_TIMBER_P2.asItem(), ModBlocks.HALF_TIMBER_P3.asItem(),
        ModBlocks.HALF_TIMBER_P4.asItem(), ModBlocks.HALF_TIMBER_P5.asItem(),
        ModBlocks.HALF_TIMBER_P6.asItem(), ModBlocks.HALF_TIMBER_P7.asItem(),
        ModBlocks.HALF_TIMBER_P8.asItem(), ModBlocks.HALF_TIMBER_P9.asItem(),
        ModBlocks.HALF_TIMBER_PILLAR_P0.asItem(), ModBlocks.HALF_TIMBER_PILLAR_P1.asItem(),
        ModBlocks.HALF_TIMBER_PILLAR_P2.asItem());

        LOGGER.info("Item Colors Registered.");
    }

    public void registerBlockRenderTypes() {
        RenderLayer transparentRenderType = RenderLayer.getCutoutMipped();
        //RenderLayer cutoutRenderType = RenderLayer.getCutout();

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P0, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P1, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P2, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P3, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P4, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P5, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P6, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P7, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P8, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_P9, transparentRenderType);

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_PILLAR_P0, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_PILLAR_P1, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.HALF_TIMBER_PILLAR_P2, transparentRenderType);

        /* BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_SIMPLE, cutoutRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_ARCH, cutoutRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_CROSS, cutoutRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_SHADE, cutoutRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_LANCET, cutoutRenderType); */

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WINDOW_PLANT, transparentRenderType);

        /* BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.FLOWER_BASKET_IRON, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.FLOWER_BASKET_GOLD, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.FLOWER_BASKET_QUARTZ, transparentRenderType); */

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_1, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_2, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_3, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_TALL_1, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_TALL_2, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DOOR_TALL_3, transparentRenderType);

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.AWNING_PURE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.AWNING_PURE_SHORT, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.AWNING_STRIPE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.AWNING_STRIPE_SHORT, transparentRenderType);

        /* BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LAMP_POST_IRON, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LAMP_POST_GOLD, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LAMP_POST_QUARTZ, transparentRenderType); */

        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CANDLE_HOLDER_IRON, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CANDLE_HOLDER_GOLD, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CANDLE_HOLDER_QUARTZ, transparentRenderType);

        //BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PHONOGRAPH, transparentRenderType);

        /* Pumpkin vines growing around...
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PUMPKIN_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PUMPKIN_CHAIR, transparentRenderType);
        // Table legs...
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.OAK_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.JUNGLE_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.ACACIA_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BIRCH_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DARK_OAK_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.SPRUCE_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CRIMSON_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WARPED_ROUND_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MANGROVE_ROUND_TABLE, transparentRenderType);
        // Glass panes...
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_TABLE, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_ROUND_TABLE, transparentRenderType);
        // Knobs...
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DRAWER, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CABINET, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DRAWER_CHEST, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CUPBOARD, transparentRenderType);
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.SHELF, transparentRenderType);
        // Holes in planters...
        BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.STONE_PLANTER, transparentRenderType); */
    }

    public void registerPropertyOverrides() {
        ModelPredicateProviderRegistry.register(ModBlocks.AWNING_PURE.asItem(), new Identifier("color"), DyeableBlockItem::getColorPropertyOverride);
        ModelPredicateProviderRegistry.register(ModBlocks.AWNING_STRIPE.asItem(), new Identifier("color"), DyeableBlockItem::getColorPropertyOverride);
        ModelPredicateProviderRegistry.register(ModBlocks.AWNING_PURE_SHORT.asItem(), new Identifier("color"), DyeableBlockItem::getColorPropertyOverride);
        ModelPredicateProviderRegistry.register(ModBlocks.AWNING_STRIPE_SHORT.asItem(), new Identifier("color"), DyeableBlockItem::getColorPropertyOverride);

        //ModelPredicateProviderRegistry.register(ModItems.PAINTING, new Identifier("type"), PaintingItem::getTypePropertyOverride);
    }

}
